<?php
namespace App\Controllers\Admin\System;

use App\Components\Admin\Node;
use App\Components\Admin\Paginator;
use App\Components\Admin\ResponseHelper;
use App\Components\Twig\Twig;
use App\Models\System\SystemRole;
use App\Models\System\SystemRoleNode;
use App\Models\System\SystemRoleUser;
use Exception;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

/**
 * 系统权限组
 */
class AuthController
{
    /**
     * 权限组列表
     * @auth
     * @menu
     */
    public function index(Request $request, Response $response)
    {
        $params = $request->getQueryParams();
        $params = array_filter($params);

        $listRs = SystemRole::orderBy('id', 'desc');
        if (isset($params['title'])) {
            $listRs = $listRs->where('title', 'like', '%' . $params['title'] . '%');
        }
        if (isset($params['describe'])) {
            $listRs = $listRs->where('describe', 'like', '%' . $params['describe'] . '%');
        }
        if (isset($params['status']) && in_array($params['status'], [1, 2])) {
            $listRs = $listRs->where('status', $params['status']);
        }
        $listRs = Paginator::paginate($listRs, $params);
        $roleIds = array_column($listRs['data'], 'id');
        if (isset($roleIds[0])) {
            $nodeRs = SystemRoleNode::selectRaw('role_id, sum(1) as node_sum')
                ->whereIn('role_id', $roleIds)
                ->groupBy('role_id')->get()->toArray();

            $userRs = SystemRoleUser::selectRaw('role_id, sum(1) as user_sum')
                ->whereIn('role_id', $roleIds)
                ->groupBy('role_id')->get()->toArray();

            foreach ($listRs['data'] as &$v) {
                $v['node'] = 0;
                $v['user'] = 0;
                foreach ($nodeRs as $v1) {
                    if ($v['id'] == $v1['role_id']) {
                        $v['node'] = $v1['node_sum'];
                        break;
                    }
                }

                foreach ($userRs as $v2) {
                    if ($v['id'] == $v2['role_id']) {
                        $v['user'] = $v2['user_sum'];
                        break;
                    }
                }
                $v['created_at'] = date('Y-m-d H:i:s', strtotime($v['created_at']));
            }
            unset($v);
        }

        $view = Twig::fromRequest($request);
        $response->getBody()->write($view->fetch('admin/system/auth/index.html', [
            'title' => '系统权限组列表',
            'list' => $listRs,
            'params' => $params,
        ]));
        return $response;
    }

    /**
     * 编辑权限组
     * @auth
     */
    public function edit(Request $request, Response $response)
    {
        if ($request->getMethod() == 'POST') {
            $params = $request->getParsedBody();
            $params = array_filter($params);
            if (!isset($params['title'])) {
                return ResponseHelper::error($response, '请输入权限组名称');
            }

            !isset($params['describe']) && $params['describe'] = '';

            if (isset($params['id']) && $params['id'] > 0) {
                $role = SystemRole::find($params['id']);
                if (!isset($role->id)) {
                    return ResponseHelper::error($response, '参数ID错误');
                }
                if ($role->title != $params['title']) {
                    $role->title = $params['title'];
                }
                if ($role->describe != $params['describe']) {
                    $role->describe = $params['describe'];
                }
                $role->save();
            } else {
                $role = new SystemRole;
                $role->title = $params['title'];
                $role->describe = $params['describe'];
                $role->status = 1;
                $role->save();
                if (!isset($role->id) || $role->id <= 0) {
                    return ResponseHelper::error($response, '权限组添加错误');
                }
            }
            return ResponseHelper::success($response);
        }

        $params = $request->getQueryParams();
        $params = array_filter($params);
        if (isset($params['id']) && $params['id'] > 0) {
            $infoRs = SystemRole::where('id', $params['id'])->first();
            if (!isset($infoRs->id)) {
                throw new Exception('权限组未找到');
            }
            $infoRs = $infoRs->toArray();

            $title = '编辑权限组';
        } else {
            $title = '新增权限组';
        }

        $view = Twig::fromRequest($request);
        $response->getBody()->write($view->fetch('admin/system/auth/edit.html', [
            'title' => $title,
            'info' => $infoRs ?? [],
        ]));
        return $response;
    }

    /**
     * 权限组状态
     * @auth
     */
    public function state(Request $request, Response $response)
    {
        if ($request->getMethod() == 'POST') {
            $params = $request->getParsedBody();
            if (!isset($params['id']) || $params['id'] <= 0) {
                return ResponseHelper::error($response, '参数ID错误');
            }
            if (isset($params['action']) && $params['action'] == 'status') {
                if (!isset($params['status']) || !in_array($params['status'], ['true', 'false'])) {
                    return ResponseHelper::error($response, '参数STATUS错误');
                }

                $updateData = ['status' => $params['status'] == 'true' ? 1 : 2];
                $updateRs = SystemRole::where('id', $params['id'])
                    ->update($updateData);
                if ($updateRs != 1) {
                    return ResponseHelper::error($response, '更新错误');
                }
                return ResponseHelper::success($response);
            } elseif (isset($params['action']) && $params['action'] == 'delete') {
                $deleteRs = SystemRole::where('id', $params['id'])->delete();
                if ($deleteRs != 1) {
                    return ResponseHelper::error($response, '删除错误');
                }
                return ResponseHelper::success($response);
            } else {
                return ResponseHelper::error($response, '参数ACTION错误');
            }
        }
    }

    /**
     * 权限节点
     * @auth
     */
    public function node(Request $request, Response $response)
    {
        if ($request->getMethod() == 'POST') {
            $params = $request->getParsedBody();
            $params = array_filter($params);
            if (!isset($params['id']) || $params['id'] <= 0) {
                return ResponseHelper::error($response, '参数错误');
            }

            $nodeRs = Node::availableNode();
            !isset($params['node']) && $params['node'] = [];
            $node = [];
            foreach ($params['node'] as $v) {
                $node[] = [
                    'method' => substr($v, strrpos($v, ':') + 1),
                    'node' => substr($v, 0, strrpos($v, ':')),
                ];
            }
            foreach ($node as $v1) {
                $isExist = false;
                foreach ($nodeRs as $v2) {
                    if ($v1['node'] != $v2['node']) {
                        continue;
                    }
                    foreach ($v2['children'] as $v3) {
                        if ($v1['method'] != $v3['node']) {
                            continue;
                        }
                        $isExist = true;
                        break;
                    }
                }
                if ($isExist === false) {
                    return ResponseHelper::error($response, '节点' . $v1['node'] . ':' . $v1['method'] . '不存在');
                }
            }
            unset($node);

            $roleRs = SystemRoleNode::select('id', 'node', 'deleted_at')
                ->where('role_id', $params['id'])
                ->withTrashed()
                ->orderBy('id', 'asc')->get()->toArray();
            foreach ($roleRs as $v) {
                if (in_array($v['node'], $params['node'])) {
                    if (isset($v['deleted_at'])) {
                        $updateRs = SystemRoleNode::where('id', $v['id'])
                            ->where('role_id', $params['id'])
                            ->where('node', $v['node'])->restore();
                        if ($updateRs != 1) {
                            return ResponseHelper::error($response, '更新权限错误');
                        }
                    }
                } else {
                    if (isset($v['deleted_at'])) {
                        continue;
                    }

                    $deleteRs = SystemRoleNode::where('id', $v['id'])
                        ->where('role_id', $params['id'])
                        ->where('node', $v['node'])->delete();
                    if ($deleteRs != 1) {
                        return ResponseHelper::error($response, '删除权限错误');
                    }
                }
            }
            $node = array_values(array_diff($params['node'], array_column($roleRs, 'node')));
            if (isset($node[0])) {
                $insertData = [];
                $nowTime = date('Y-m-d H:i:s');
                foreach ($node as $v) {
                    $insertData[] = [
                        'role_id' => $params['id'],
                        'node' => $v,
                        'created_at' => $nowTime,
                        'updated_at' => $nowTime,
                    ];
                }
                SystemRoleNode::insert($insertData);
            }

            SystemRole::clearNodeCache($params['id']);

            return ResponseHelper::success($response);
        }
        $params = $request->getQueryParams();
        $params = array_filter($params);
        if (!isset($params['id']) || $params['id'] <= 0) {
            throw new Exception('参数错误');
        }

        $infoRs = SystemRole::select('id', 'title', 'status')
            ->where('id', $params['id'])->first();
        if (!isset($infoRs->id)) {
            throw new Exception('权限组未找到');
        }

        $nodeRs = Node::availableNode();

        $roleRs = SystemRoleNode::select('id', 'node')
            ->where('role_id', $params['id'])
            ->orderBy('id', 'asc')->get()->toArray();
        foreach ($roleRs as $k => $v) {
            if (strpos($v['node'], ':') === false) {
                continue;
            }
            $roleRs[$k]['method'] = substr($v['node'], strrpos($v['node'], ':') + 1);
            $roleRs[$k]['node'] = substr($v['node'], 0, strrpos($v['node'], ':'));
        }

        foreach ($nodeRs as $k1 => $v1) {
            $ownNum = 0;
            foreach ($roleRs as $v2) {
                if ($v1['node'] != $v2['node']) {
                    continue;
                }

                foreach ($v1['children'] as $k3 => $v3) {
                    if ($v3['node'] != $v2['method']) {
                        continue;
                    }
                    $nodeRs[$k1]['children'][$k3]['own'] = true;
                    $ownNum += 1;
                }
            }

            if ($ownNum > 0 && $ownNum == count($v1['children'])) {
                $nodeRs[$k1]['own'] = true;
            }
        }
        unset($roleRs);

        $view = Twig::fromRequest($request);
        $response->getBody()->write($view->fetch('admin/system/auth/node.html', [
            'title' => '系统权限组列表',
            'info' => $infoRs,
            'list' => $nodeRs,
        ]));
        return $response;
    }
}
